﻿@{
    Layout = "~/Views/Shared/_Layout_Turorials.cshtml";
}
<h1>Developing a Client </h1>

<p>Once we have our grain type implemented, we can write a client application that uses the type.</p>

<p>The following Orleans DLLs from either the <code class="highlighter-rouge">[SDK-ROOT]\Binaries\PresenceClient_ or _[SDK-ROOT]\Samples\References</code> directories need to be referenced in the client application project:</p>

<ul>
    <li>Orleans.dll</li>
    <li>OrleansRuntimeInterfaces.dll</li>
</ul>

<p>
    Almost any client will involve use of the grain factory class.
    The <code class="highlighter-rouge">GetGrain()</code> method is used for getting a grain reference for a particular ID.
    As was already mentioned, grains cannot be explicitly created or deleted.
</p>

<div class="language-csharp highlighter-rouge">
    <pre class="highlight"><code><span class="n">GrainClient</span><span class="p">.</span><span class="nf">Initialize</span><span class="p">();</span>
<span class="c1">// Hardcoded player ID
</span><span class="n">Guid</span> <span class="n">playerId</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Guid</span><span class="p">(</span><span class="s">"{2349992C-860A-4EDA-9590-000000000006}"</span><span class="p">);</span>
<span class="n">IPlayerGrain</span> <span class="n">player</span> <span class="p">=</span> <span class="n">GrainClient</span><span class="p">.</span><span class="n">GrainFactory</span><span class="p">.</span><span class="n">GetGrain</span><span class="p">&lt;</span><span class="n">IPlayerGrain</span><span class="p">&gt;(</span><span class="n">playerId</span><span class="p">);</span>
<span class="n">IGameGrain</span> <span class="n">game</span> <span class="p">=</span> <span class="n">player</span><span class="p">.</span><span class="n">CurrentGame</span><span class="p">.</span><span class="n">Result</span><span class="p">;</span>
<span class="n">var</span> <span class="n">watcher</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">GameObserver</span><span class="p">();</span>
<span class="n">var</span> <span class="n">observer</span> <span class="p">=</span> <span class="n">GrainClient</span><span class="p">.</span><span class="n">GrainFactory</span><span class="p">.</span><span class="n">CreateObjectReference</span><span class="p">&lt;</span><span class="n">IGameObserver</span><span class="p">&gt;(</span><span class="n">watcher</span><span class="p">);</span>
<span class="n">await</span> <span class="n">game</span><span class="p">.</span><span class="nf">SubscribeForGameUpdates</span><span class="p">();</span>
</code></pre>
</div>

<p>If this code is used from the main thread of a console application, you have to call <code class="highlighter-rouge">Wait()</code> on the task returned by <code class="highlighter-rouge">game.SubscribeForGameUpdates()</code> because <code class="highlighter-rouge">await</code> does not prevent the <code class="highlighter-rouge">Main()</code> function from returning, which will cause the client process to exit.</p>

<p>See the Key Concepts section for more details on the various ways to use <code class="highlighter-rouge">Task</code>s for execution scheduling and exception flow.</p>

<h2 id="find-or-create-grains">Find or create grains</h2>

<p>After establishing a connection by calling <code class="highlighter-rouge">GrainClient.Initialize()</code>, static methods in the generic factory class may be used to get a reference to a grain, such as <code class="highlighter-rouge">GrainClient.GrainFactory.GetGrain&lt;IPlayerGrain&gt;()</code> for the <code class="highlighter-rouge">PlayerGrain</code>. The grain interface is passed as a type argument to <code class="highlighter-rouge">GrainFactory.GetGrain&lt;T&gt;()</code>.</p>

<h2 id="sending-messages-to-grains">Sending messages to grains</h2>

<p>
    The programming model for communicating with grains from a client is almost the same as from a grain.
    The client holds grain references which implement a grain interface like <code class="highlighter-rouge">IPlayerGrain</code>.
    It invokes methods on that grain reference, and these return asynchronous values: <code class="highlighter-rouge">Task</code>/<code class="highlighter-rouge">Task&lt;T&gt;</code>, or another grain interface inheriting from <code class="highlighter-rouge">IGrain</code>.
    The client can use the <code class="highlighter-rouge">await</code> keyword or <code class="highlighter-rouge">ContinueWith()</code> method to queue continuations to be executed when these asynchronous values resolve, or the <code class="highlighter-rouge">Wait()</code> method to block the current thread.
</p>

<p>
    The one key difference between communicating with a grain from within a client or from within another grain is the single-threaded execution model.
    Grains are constrained to be single-threaded by the Orleans scheduler, while clients may be multi-threaded.
    The client library uses the TPL thread pool to manage continuations and callbacks, and so it is up to the client to manage its own concurrency using whatever synchronization constructs are appropriate for its environment – locks, events, TPL tasks, etc.
</p>

<h2 id="receiving-notifications">Receiving notifications</h2>

<p>
    There are situations in which a simple message/response pattern is not enough, and the client needs to receive asynchronous notifications.
    For example, a user might want to be notified when a new message has been published by someone that she is following.
</p>

<p>
    An observer is a one-way asynchronous interface that inherits from <code class="highlighter-rouge">IGrainObserver</code>, and all its methods must be <code class="highlighter-rouge">void</code>.
    The grain sends a notification to the observer by invoking it like a grain interface method, except that it has no return value, and so the grain need not depend on the result.
    The Orleans runtime will ensure one-way delivery of the notifications.
    A grain that publishes such notifications should provide an API to add or remove observers.
</p>

<p>
    To subscribe to a notification, the client must first create a local C# object that implements the observer interface.
    It then calls <code class="highlighter-rouge">CreateObjectReference()</code> method on the grain factory, to turn the C# object into a grain reference, which can then be passed to the subscription method on the notifying grain.
</p>

<p>
    This model can also be used by other grains to receive asynchronous notifications.
    Unlike in the client subscription case, the subscribing grain simply implements the observer interface as a facet, and passes in a reference to itself (e.g. <code class="highlighter-rouge">this.AsReference&lt;IChirperViewer&gt;</code>).
</p>

<h2 id="example">Example</h2>

<p>Here is an extended version of the example given above of a client application that connects to Orleans, finds the player account, subscribes for updates to the game session the player is part of, and prints out notifications until the program is manually terminated.</p>

<div class="language-csharp highlighter-rouge">
    <pre class="highlight"><code><span class="k">namespace</span> <span class="nn">PlayerWatcher</span>
<span class="p">{</span>
    <span class="k">class</span> <span class="nc">Program</span>
    <span class="p">{</span>
    <span class="c1">/// &lt;summary&gt;
</span>        <span class="c1">/// Simulates a companion application that connects to the game
</span>        <span class="c1">/// that a particular player is currently part of, and subscribes
</span>        <span class="c1">/// to receive live notifications about its progress.
</span>        <span class="c1">/// &lt;/summary&gt;
</span>        <span class="k">static</span> <span class="k">void</span> <span class="nf">Main</span><span class="p">(</span><span class="kt">string</span><span class="p">[]</span> <span class="n">args</span><span class="p">)</span>
    <span class="p">{</span>
    <span class="k">try</span>
    <span class="p">{</span>
    <span class="n">GrainClient</span><span class="p">.</span><span class="nf">Initialize</span><span class="p">();</span>
    <span class="c1">// Hardcoded player ID
</span>                <span class="n">Guid</span> <span class="n">playerId</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Guid</span><span class="p">(</span><span class="s">"{2349992C-860A-4EDA-9590-000000000006}"</span><span class="p">);</span>
    <span class="n">IPlayerGrain</span> <span class="n">player</span> <span class="p">=</span> <span class="n">GrainClient</span><span class="p">.</span><span class="n">GrainFactory</span><span class="p">.</span><span class="n">GetGrain</span><span class="p">&lt;</span><span class="n">IPlayerGrain</span><span class="p">&gt;(</span><span class="n">playerId</span><span class="p">);</span>
    <span class="n">IGameGrain</span> <span class="n">game</span> <span class="p">=</span> <span class="k">null</span><span class="p">;</span>
    <span class="k">while</span> <span class="p">(</span><span class="n">game</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span>
    <span class="p">{</span>
    <span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="s">"Getting current game for player {0}..."</span><span class="p">,</span> <span class="n">playerId</span><span class="p">);</span>
    <span class="k">try</span>
    <span class="p">{</span>
    <span class="n">game</span> <span class="p">=</span> <span class="n">player</span><span class="p">.</span><span class="n">CurrentGame</span><span class="p">.</span><span class="n">Result</span><span class="p">;</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">game</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span> <span class="c1">// Wait until the player joins a game
</span>                            <span class="n">Thread</span><span class="p">.</span><span class="nf">Sleep</span><span class="p">(</span><span class="m">5000</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">exc</span><span class="p">)</span>
    <span class="p">{</span>
    <span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="s">"Exception: "</span><span class="p">,</span> <span class="n">exc</span><span class="p">.</span><span class="nf">GetBaseException</span><span class="p">());</span>
    <span class="p">}</span>
    <span class="p">}</span>
    <span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="s">"Subscribing to updates for game {0}..."</span><span class="p">,</span> <span class="n">game</span><span class="p">.</span><span class="nf">GetPrimaryKey</span><span class="p">());</span>
    <span class="c1">// Subscribe for updates
</span>                <span class="n">var</span> <span class="n">watcher</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">GameObserver</span><span class="p">();</span>
    <span class="n">game</span><span class="p">.</span><span class="nf">SubscribeForGameUpdates</span><span class="p">(</span><span class="n">GrainClient</span><span class="p">.</span><span class="n">GrainFactory</span><span class="p">.</span><span class="n">CreateObjectReference</span><span class="p">&lt;</span><span class="n">IGameObserver</span><span class="p">&gt;(</span><span class="n">watcher</span><span class="p">)).</span><span class="nf">Wait</span><span class="p">();</span>
    <span class="c1">// .Wait will block main thread so that the process doesn't exit.
</span>                <span class="c1">// Updates arrive on thread pool threads.
</span>                <span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="s">"Subscribed successfully. Press &lt;Enter&gt; to stop."</span><span class="p">);</span>
    <span class="n">Console</span><span class="p">.</span><span class="nf">ReadLine</span><span class="p">();</span>
    <span class="p">}</span>
    <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">exc</span><span class="p">)</span>
    <span class="p">{</span>
    <span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="s">"Unexpected Error: {0}"</span><span class="p">,</span> <span class="n">exc</span><span class="p">.</span><span class="nf">GetBaseException</span><span class="p">());</span>
    <span class="p">}</span>
    <span class="p">}</span>
    <span class="c1">/// &lt;summary&gt;
</span>        <span class="c1">/// Observer class that implements the observer interface.
</span>        <span class="c1">/// Need to pass a grain reference to an instance of this class to subscribe for updates.
</span>        <span class="c1">/// &lt;/summary&gt;
</span>        <span class="k">private</span> <span class="k">class</span> <span class="nc">GameObserver</span> <span class="p">:</span> <span class="n">IGameObserver</span>
    <span class="p">{</span>
    <span class="c1">// Receive updates
</span>            <span class="k">public</span> <span class="k">void</span> <span class="nf">UpdateGameScore</span><span class="p">(</span><span class="kt">string</span> <span class="n">score</span><span class="p">)</span>
    <span class="p">{</span>
    <span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="s">"New game score: {0}"</span><span class="p">,</span> <span class="n">score</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>

<h2 id="next">Next</h2>

<p><a href="Running-the-Application">Running the Application</a></p> 